package work.soho.proxy.component.impl;

import work.soho.proxy.ConfigManage;
import work.soho.proxy.ProxyApplication;
import work.soho.proxy.aliyun.parts.*;
import work.soho.proxy.component.IComponent;
import work.soho.proxy.socket5.Socket5Thread;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

import static work.soho.proxy.aliyun.parts.PartsManage.getPartByName;

/**
 * 纯Java实现代理功能
 *
 */
public class JavaSocket5Impl implements IComponent {
    private ConfigManage configManage;

    /**
     * proxy，register 检查线程
     */
    private Thread thread = null;

    /**
     * 获取代理服务器IP地址
     */
    private String proxyServerIp = "";

    /**
     * 服务器实例检查
     */
    private Thread instanceCheckThread;

    public ConfigManage getConfigManage() {
        return configManage;
    }

    public void setConfigManage(ConfigManage configManage) {
        this.configManage = configManage;
    }

    public JavaSocket5Impl() {
        setConfigManage(ProxyApplication.configManage);
    }

    /**
     * 启动socket5代理
     *
     * @return
     */
    @Override
    public boolean  start() {

        synchronized(this) {
            //检查启动服务器相关实例没有释放掉
            if(instanceCheckThread==null) {
                instanceCheckThread = new Thread(()->{
                    ArrayList<String> list = new ArrayList<>();
                    list.add(ImportKeyPairPart.class.getName()); //导入密钥对
                    list.add(VpcPart.class.getName()); //虚拟网络
                    list.add(SwitchPart.class.getName()); //交换机
                    list.add(SecurityGroupPart.class.getName()); //安全组
                    list.add(ServerInstancePart.class.getName()); //服务器实例

                    do {
                        PartsManage.check(list);
                        try {
                            Thread.sleep(20 * 1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } while (true);
                });
                instanceCheckThread.start();
            }



            if(thread == null) {
                thread = new Thread(() -> {
                    ServerSocket server = null;
                    try {
                        System.out.println("启动代理服务：at 0.0.0.0:" + Integer.parseInt(getConfigManage().getPartsConfigure().getProxyPort()));
                        server = new ServerSocket(Integer.parseInt(getConfigManage().getPartsConfigure().getProxyPort()), 50, InetAddress.getByName("0.0.0.0"));
                    } catch (IOException e) {
                        e.printStackTrace();
                        return;
                    }

                    do {
                        try {
                            Socket client = server.accept();
                            Socket5Thread socket5Thread = new Socket5Thread(client
                                    ,getProxyServerIp()
                                    , 22
                                    , "root"
                                    , getConfigManage().getPartsConfigure().getLocalPrivateKeyFile(), null);
                            socket5Thread.start();
                        } catch (IOException ioException) {
                            ioException.printStackTrace();
                        }
                    } while(true);
                });
                thread.start();
            }
        }
        return false;
    }

    /**
     * 获取服务器端IP地址
     *
     * 添加线程定时同步服务器端IP地址
     *
     * @return
     */
    public synchronized String getProxyServerIp() {
        if("".equals(proxyServerIp)) {
            (new Thread(() ->{
                //获取代理服务器IP相关信息
                ServerInstancePart serverInstancePart = (ServerInstancePart) getPartByName(ServerInstancePart.class.getName());
                String serverIp = null;
                do {
                    serverIp = serverInstancePart.getWIp();
                    if(serverIp != null) {
                        break;
                    }
                    try {
                        Thread.sleep(120 * 1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } while(serverIp==null);
                proxyServerIp = serverIp;
                proxyServerIp.notify();
            })).start();

            try {
                proxyServerIp.wait();
            } catch (Exception e) {
                //ignore
                e.printStackTrace();
            }

        }
        return proxyServerIp;
    }

    @Override
    public boolean stop() {
        //nothing todo
        return false;
    }

    @Override
    public boolean unRegister() {
        return false;
    }

    /**
     * 检查守护端口是否在使用
     *
     * @return
     */
    public boolean isPortUsed() {
        try {
            Socket socket = new Socket("127.0.0.1", Integer.parseInt(configManage.getPartsConfigure().getProxyPort()));
            socket.close();
            return true;
        } catch (IOException e) {
            //nothing todo
        }
        return false;
    }
}
